package cn.bon.security.filter;

import cn.bon.common.tool.RedisUtils;
import cn.bon.common.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import jakarta.annotation.Resource;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author: dronff
 * @description:
 * @CreateTime: 2023/12/8 8:46
 **/
@Component
@AllArgsConstructor
//@RequiredArgsConstructor()
@Data
public class JwtAuthFilter implements Filter {
    @Resource
    private JwtUtils jwtUtils;
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = null;
        HttpServletResponse httpServletResponse = null;
        if (servletRequest instanceof HttpServletRequest ){
            httpServletRequest = (HttpServletRequest) servletRequest;
        }
        if (servletResponse instanceof HttpServletResponse ){
            httpServletResponse = (HttpServletResponse) servletResponse;
        }
        // 获取token
        String tk = httpServletRequest.getHeader("tk");
        if (tk != null && !tk.trim().isEmpty()) {
            Claims claims = jwtUtils.getClaimsFromToken(tk);
            if (claims == null) {
                // 非法token
                filterChain.doFilter(servletRequest,servletResponse);
                return;
            }
            Map map = (Map) RedisUtils.get("user:login:" + claims.get("username").toString());
            if (map == null || map.get("token") == null || !tk.equals(map.get("token")) || claims.getExpiration().before(new Date())) {
                // 该token不存在于redis或已过期
                // token过期 响应头中添加清除token
                httpServletResponse.addHeader(
                        "clear-tk","true"
                );
                filterChain.doFilter(servletRequest,servletResponse);
                return;
            }
            String username = claims.get("username", String.class);
            List auths = (List)((Map)map.get("authentication")).get("authorities");
            List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
            grantedAuthorities.add(new SimpleGrantedAuthority("simple"));
            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(username, null, grantedAuthorities);
            SecurityContextHolder
                    .getContext()
                    .setAuthentication(usernamePasswordAuthenticationToken);
        }
        filterChain.doFilter(servletRequest,servletResponse);

    }
    private void authFailed(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        filterChain.doFilter(httpServletRequest,httpServletResponse);
    }
}
